home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / exec / obtainsemaphoreshared.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  3KB  |  110 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: obtainsemaphoreshared.c,v 1.4 1996/08/13 13:56:04 digulla Exp $
  4.     $Log: obtainsemaphoreshared.c,v $
  5.     Revision 1.4  1996/08/13 13:56:04  digulla
  6.     Replaced __AROS_LA by __AROS_LHA
  7.     Replaced some __AROS_LH*I by __AROS_LH*
  8.     Sorted and added includes
  9.  
  10.     Revision 1.3  1996/08/01 17:41:14  digulla
  11.     Added standard header for all files
  12.  
  13.     Desc:
  14.     Lang: english
  15. */
  16. #include "exec_intern.h"
  17. #include "semaphores.h"
  18.  
  19. /*****************************************************************************
  20.  
  21.     NAME */
  22.     #include <exec/semaphores.h>
  23.     #include <clib/exec_protos.h>
  24.  
  25.     __AROS_LH1(void, ObtainSemaphoreShared,
  26.  
  27. /*  SYNOPSIS */
  28.     __AROS_LHA(struct SignalSemaphore *, sigSem, A0),
  29.  
  30. /*  LOCATION */
  31.     struct ExecBase *, SysBase, 113, Exec)
  32.  
  33. /*  FUNCTION
  34.     Get a shared lock on a semaphore. If the lock cannot be obtained
  35.     immediately this function waits. There may be more than one shared
  36.     locks at the same time but only one exclusive one. An exclusive
  37.     lock prevents shared locks. Shared locks are released with
  38.     ReleaseSemaphore().
  39.  
  40.     INPUTS
  41.     sigSem - Pointer to semaphore structure
  42.  
  43.     RESULT
  44.  
  45.     NOTES
  46.     This function preserves all registers.
  47.  
  48.     EXAMPLE
  49.  
  50.     BUGS
  51.  
  52.     SEE ALSO
  53.     ReleaseSemaphore()
  54.  
  55.     INTERNALS
  56.  
  57.     HISTORY
  58.     29-10-95    digulla automatically created from
  59.                 exec_lib.fd and clib/exec_protos.h
  60.     21-01-96    fleischer implementation
  61.  
  62. *****************************************************************************/
  63. {
  64.     __AROS_FUNC_INIT
  65.     __AROS_BASE_EXT_DECL(struct ExecBase *,SysBase)
  66.     struct Task *me;
  67.  
  68.     /* Get pointer to current task */
  69.     me=SysBase->ThisTask;
  70.  
  71.     /* Arbitrate for the semaphore structure */
  72.     Forbid();
  73.  
  74.     /* Check if there's an exclusive lock on the semaphore */
  75.     if(sigSem->ss_NestCount>0)
  76.     {
  77.     /* Yes. Is it owned by the current task? */
  78.     if(sigSem->ss_Owner!=me)
  79.     {
  80.         /* No. Prepare a node for the waiting queue. */
  81.         struct SemaphoreNode sn;
  82.         sn.node.ln_Pri =SN_TYPE_OBTAIN;
  83.         sn.node.ln_Name=(char *)SM_SHARED;
  84.         sn.task       =me;
  85.  
  86.         /* Add it. */
  87.         AddTail((struct List *)&sigSem->ss_WaitQueue,&sn.node);
  88.  
  89.         /* Wait until the semaphore is free */
  90.         Wait(SEMAPHORESIGF);
  91.  
  92.         /* ss_NestCount and ss_Owner are already set by ReleaseSemaphore() */
  93.     }else
  94.         /* Add one nesting level more */
  95.         sigSem->ss_NestCount++;
  96.     }else
  97.     {
  98.     /* There's no exclusive lock on the semaphore. Get a shared one. */
  99.     sigSem->ss_NestCount--;
  100.  
  101.     /* Invalidate the owner field - so no task may think this semaphore is his. */
  102.     sigSem->ss_Owner=NULL;
  103.     }
  104.  
  105.     /* All done. */
  106.     Permit();
  107.     __AROS_FUNC_EXIT
  108. } /* ObtainSemaphoreShared */
  109.  
  110.